<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件绑定示例</title>
    <script>
        window.onload = function () {
            var btn = document.getElementById("btn01");

            /**
             * 方式一：使用 obj.事件名 = 函数 的方式绑定事件
             * - 缺点：同一个对象的同一个事件只能绑定一个函数，多次绑定会覆盖前面的
             */
            // btn.onclick = function () {
            //     alert("1");
            // }
            // btn.onclick = function () {
            //     alert("2");  // 只有这个生效
            // }

            /**
             * 方式二：使用 addEventListener 绑定事件（推荐）
             * - 支持多个监听器
             * - 参数：
             *   1. 事件类型（字符串，不带 on）
             *   2. 回调函数
             *   3. 是否在捕获阶段触发（一般为 false）
             */
            // btn.addEventListener("click", function () {
            //     alert("1");
            // }, false);
            //
            // btn.addEventListener("click", function () {
            //     alert("2");
            // }, false);
            //
            // btn.addEventListener("click", function () {
            //     alert("3");
            // }, false);

            /**
             * 方式三：使用 attachEvent 绑定事件（IE8 及以下专用）
             * - 执行顺序是倒序的（后绑定的先执行）
             * - 参数：
             *   1. 事件名称（必须带 on）
             *   2. 回调函数
             */
            // btn.attachEvent("onclick", function () {
            //     alert("1");
            // });
            // btn.attachEvent("onclick", function () {
            //     alert("2");
            // });
            // btn.attachEvent("onclick", function () {
            //     alert("3");
            // });

            /**
             * this 指向问题：
             * - addEventListener 中的 this → 当前绑定对象（btn）
             * - attachEvent 中的 this → window（这是个坑！）
             */
            // btn.addEventListener("click", function () {
            //     alert(this);  // 输出 [object HTMLButtonElement]
            // }, false);
            //
            // btn.attachEvent("onclick", function () {
            //     alert(this);  // 输出 [object Window]
            // });

            /**
             * 封装一个兼容性的事件绑定函数 bindEvent
             * @param obj       要绑定事件的对象（元素）
             * @param eventStr  事件类型（如 "click"，不要带 on）
             * @param callback  回调函数
             */
            function bindEvent(obj, eventStr, callback) {
                if (obj.addEventListener) {
                    // 标准浏览器支持 addEventListener
                    obj.addEventListener(eventStr, callback, false);
                } else {
                    // IE8 及以下使用 attachEvent
                    // 利用 call 修改 this 指向，使其指向 obj
                    obj.attachEvent("on" + eventStr, function () {
                        //call() 方法使用一个指定的 this 值和单独给出的参数来调用一个函数。
                        callback.call(obj);
                    });
                }
            }

            // 使用封装好的 bindEvent 方法绑定点击事件
            bindEvent(btn, "click", function () {
                alert("第一个事件");
            });

            bindEvent(btn, "click", function () {
                alert("第二个事件");
            });

        };
    </script>
</head>
<body>
<button id="btn01">点我</button>
</body>
</html>
